package com.ecr.hub.service.destination.impl;

import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.ecr.hub.ApplicationException;
import com.ecr.hub.DaoApplicationException;
import com.ecr.hub.RailDestinationException;
import com.ecr.hub.database.dao.IDaoDestination;
import com.ecr.hub.database.dao.IDaoRail;
import com.ecr.hub.model.destination.Destination;
import com.ecr.hub.model.destination.DestinationRailTranscoder;
import com.ecr.hub.model.rail.Rail;
import com.ecr.hub.service.destination.IDestinationManager;

@Service("destinationManager")
public class DestinationManagerImpl implements IDestinationManager {

	// Dao pour les destinations.
	@Resource(name = "daoDestination")
	IDaoDestination daoDestination;

	// Dao pour les voies.
	@Resource(name = "daoRail")
	IDaoRail daoRail;

	/**
	 * Récupération de la liste de toutes les destinations actives.
	 */
	@Override
	public List<Destination> getAllList() throws ApplicationException {
		try {
			return daoDestination.getAllList();
		} catch (DataAccessException e) {
			throw new DaoApplicationException(e);
		} catch (Exception e) {
			throw new ApplicationException(e);
		}
	}

	/**
	 * Création d'une nouvelle destination.
	 */
	@Override
	public void create(Destination destination) throws ApplicationException {
		try {
			destination.setCreationDate(new Date());
			destination.setId(daoDestination.create(destination));
		} catch (DataAccessException e) {
			throw new DaoApplicationException(e);
		} catch (Exception e) {
			throw new ApplicationException(e);
		}
	}

	/**
	 * Modification des paramètres d'une voie. Comme on a pris l'option de ne
	 * pas faire de relationnel entre la voie et la destination (les infos de la
	 * destination sont directement copiées dans la voie, il faut par contre
	 * réappliquer les modifications dans les voies qui contiennent la
	 * destination.
	 */
	@Override
	@Transactional
	public void update(Destination destination) throws ApplicationException {
		try {
			daoDestination.update(destination);
			daoRail.updateForDestination(destination.getId(),
					destination.getLabel(), destination.getHexColor());
		} catch (DataAccessException e) {
			throw new DaoApplicationException(e);
		} catch (Exception e) {
			throw new ApplicationException(e);
		}
	}

	/**
	 * Suppression d'une destination. On vérifie que la destination n'est pas
	 * attachée à une voie.
	 */
	@Override
	public void delete(Destination destination) throws ApplicationException {
		try {
			List<Rail> lstRails = daoRail.getByDestinationId(destination
					.getId());
			if (lstRails.size() > 0)
				throw new RailDestinationException(
						"Hub : la destination est encore affectée à une voie.");

			daoDestination.delete(destination);
		} catch (RailDestinationException e) {
			throw e;
		} catch (DataAccessException e) {
			throw new DaoApplicationException(e);
		} catch (Exception e) {
			throw new ApplicationException(e);
		}
	}

	/**
	 * Récupération de la liste des correspondances entre les voies et les
	 * destinations.
	 */
	@Override
	public List<DestinationRailTranscoder> getListDestinationsRail()
			throws ApplicationException {
		try {
			return daoDestination.getListDestinationsRail();
		} catch (DataAccessException e) {
			throw new DaoApplicationException(e);
		} catch (Exception e) {
			throw new ApplicationException(e);
		}
	}
}
